package com.ruoyi.web.controller.net;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.net.constant.UdpConstants;
import com.ruoyi.net.domain.NetElement;
import com.ruoyi.net.netconf.Device;
import com.ruoyi.net.netconf.util.DeviceManager;
import com.ruoyi.net.service.INetElementService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.util.StringUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.net.domain.ElementAlarm;
import com.ruoyi.net.service.IElementAlarmService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 网元-告警Controller
 * 
 * @author net
 * @date 2024-11-17
 */
@Api(tags = "网元-告警")
@RestController
@RequestMapping("/element/alarm")
public class ElementAlarmController extends BaseController
{
    @Autowired
    private DatagramSocket socket;

    @Autowired
    private IElementAlarmService elementAlarmService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private INetElementService netElementService;

    @Autowired
    private DeviceManager deviceManager;

    /**
     * 发送查询告警-WS向M查询某NE所有盘告警
     */
    @ApiOperation(value = "读取性能管理-性能列表", httpMethod = "GET")
//    @PreAuthorize("@ss.hasPermi('net:performance:list')")
    @GetMapping("/send/{ip}")
    public AjaxResult send(@PathVariable("ip") String ip)
    {
        boolean isSend = sendQueryAlarm(ip);
        if (!isSend) {
            return AjaxResult.error("发送失败");
        }
        return AjaxResult.success();
    }

    private boolean sendQueryAlarm(String ip) {
        boolean isSend = true;
        byte sno = 0;
        try {
            InetAddress targetAddress = InetAddress.getByName(ip);
            // 要发送的数据
            sno = (byte)ThreadLocalRandom.current().nextInt(Byte.MAX_VALUE);

            // 28 + 21 告警 JC0421 0x9,
            char[] bytes = {0x0, 0x0, 0x0, 0x4f, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x82, 0x46, 0x48, 0x4d, 0x50, 0x2, 0xe1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x4c, 0x0, 0x0, 0x0, 0x72,
                    0x4a, 0x43, 0x4, 0x21, 0x88, 0x0, 0x31, 0x0, 0x0, 0x81, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d,
                    0x80, 0x1, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};

            ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
            for (int i = 0; i < bytes.length; i++) {
                if (i == 23 || i == 38) { //0x4c
                    buffer.put(sno);
                } else {
                    buffer.put((byte) bytes[i]);
                }
            }
            buffer.flip();
            byte[] sendData = buffer.array();
            // fos 28
            // 协议头21字节
            // 15字节
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, targetAddress, UdpConstants.UDP_PORT);
            socket.send(sendPacket);

//            logger.info("查询告警数据已发送");
        } catch (Exception e) {
            logger.info("查询告警数据发送失败：" + e.getMessage());
            isSend = false;
        }
        return isSend;
    }

    /**
     * 读取网元-告警列表
     */
    @ApiOperation(value = "读取网元-告警列表", httpMethod = "GET")
    //    @PreAuthorize("@ss.hasPermi('system:alarm:list')")
    @GetMapping("/read")
    public TableDataInfo read(ElementAlarm elementAlarm)
    {
        startPage();
        List<ElementAlarm> list = new ArrayList<>();
        return getDIYPageTable(list);
    }

    /**
     * 查询网元-告警列表
     */
    @ApiOperation(value = "查询网元-告警列表", httpMethod = "GET")
    //    @PreAuthorize("@ss.hasPermi('system:alarm:list')")
    @GetMapping("/list")
    public TableDataInfo list(ElementAlarm elementAlarm) {

        boolean isSend = 1 == Convert.toInt(ServletUtils.getParameter(TableSupport.PAGE_NUM), 1);

        startPage();
        // 第一页的时候发送性能查询命令
        if (isSend && StringUtils.isNotEmpty(elementAlarm.getElementId())) {
            NetElement netElement = netElementService.getCacheObject(elementAlarm.getElementId().replaceAll(CacheConstants.NET_ELEMENT_KEY, ""));
            // 校时
            time(netElement.getIp());
            sendQueryAlarm(netElement.getIp());
        }
        List<ElementAlarm> list = elementAlarmService.selectElementAlarmList(elementAlarm);
        convertSeconds(list);
        return getDataTable(list);
    }

    /**
     * 校时
     * @param ip
     */
    private void time(String ip) {
        Device device = deviceManager.getDevice(ip);
        if (device.isConnected()) {
            // 手动设置系统时间
            deviceManager.executeRPC("<set-systime xmlns=\"http://fiberhome.com/fhnw/yang/systemmanage/fos-system-oper\">" +
                    "<date-time>" + DateUtils.getTime() + "</date-time>" +
                    "<type>LOCAL</type>" +
                    "</set-systime>");

            /*
            设置netconf 命令兼容模式 todo 2025-02-14 和小二沟通
             */
            deviceManager.editConfig("<ext-nms xmlns=\"http://fiberhome.com/fhnw/yang/fos-extension-nms\">" +
                    "        <netconf-ignore-unknown-node>" +
                    "          <enabled>enable</enabled>" +
                    "        </netconf-ignore-unknown-node>" +
                    "      </ext-nms>", "merge");
        }
    }

    private void convertSeconds(List<ElementAlarm> list) {
        for (ElementAlarm alarm : list) {
            if (!StringUtils.isEmpty(alarm.getAlarmContinueDuration())) {
                int totalSeconds = Integer.parseInt(alarm.getAlarmContinueDuration());
                int days = totalSeconds / (24 * 3600);
                totalSeconds %= (24 * 3600);
                int hours = totalSeconds / 3600;
                totalSeconds %= 3600;
                int minutes = totalSeconds / 60;
                int seconds = totalSeconds % 60;
                alarm.setAlarmContinueDuration(days + "天" + hours + "时" + minutes + "分" + seconds + "秒");
            }
        }
    }

    /**
     * 导出网元-告警列表
     */
    @ApiOperation(value = "导出网元-告警列表", httpMethod = "POST")
    //    @PreAuthorize("@ss.hasPermi('system:alarm:export')")
    @Log(title = "网元-告警", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ElementAlarm elementAlarm)
    {
        List<ElementAlarm> list = elementAlarmService.selectElementAlarmList(elementAlarm);
        ExcelUtil<ElementAlarm> util = new ExcelUtil<ElementAlarm>(ElementAlarm.class);
        util.exportExcel(response, list, "网元-告警数据");
    }

    /**
     * 获取网元-告警详细信息
     */
    @ApiOperation(value = "获取网元-告警详细信息", httpMethod = "GET")
    //    @PreAuthorize("@ss.hasPermi('system:alarm:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        return success(elementAlarmService.selectElementAlarmById(id));
    }

    /**
     * 新增网元-告警
     */
    @ApiOperation(value = "新增网元-告警", httpMethod = "POST")
    //    @PreAuthorize("@ss.hasPermi('system:alarm:add')")
    @Log(title = "网元-告警", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ElementAlarm elementAlarm)
    {
        return toAjax(elementAlarmService.insertElementAlarm(elementAlarm));
    }

    /**
     * 修改网元-告警
     */
    @ApiOperation(value = "修改网元-告警", httpMethod = "PUT")
    //    @PreAuthorize("@ss.hasPermi('system:alarm:edit')")
    @Log(title = "网元-告警", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ElementAlarm elementAlarm)
    {
        return toAjax(elementAlarmService.updateElementAlarm(elementAlarm));
    }

    /**
     * 删除网元-告警
     */
    @ApiOperation(value = "删除网元-告警", httpMethod = "DELETE")
    //    @PreAuthorize("@ss.hasPermi('system:alarm:remove')")
    @Log(title = "网元-告警", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids)
    {
        return toAjax(elementAlarmService.deleteElementAlarmByIds(ids));
    }
}
